package com.senlingspace.quartz.task;

import com.alibaba.fastjson2.JSON;
import com.google.common.base.Splitter;
import com.senlingspace.common.core.redis.RedisCache;
import com.senlingspace.common.enums.*;
import com.senlingspace.common.utils.DateUtils;
import com.senlingspace.common.utils.StringUtils;
import com.senlingspace.payment.lakala.bean.response.TradeQueryResponse;
import com.senlingspace.payment.lakala.service.LakalaMicroPayService;
import com.senlingspace.system.domain.SlkjOrder;
import com.senlingspace.system.domain.SlkjOrderStatusCompensation;
import com.senlingspace.system.domain.SlkjOrderStatusLog;
import com.senlingspace.system.mapper.SlkjOrderStatusLogMapper;
import com.senlingspace.system.mapper.SlkjShoppingCartMapper;
import com.senlingspace.system.service.ISlkjOrderService;
import com.senlingspace.system.service.ISlkjOrderStatusCompensationService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.List;
import java.util.Objects;

/**
 * 订单状态补偿任务
 *
 * @author lebronjames
 * @date 2024/10/29
 */
@Slf4j
@Component
@AllArgsConstructor
public class OrderStatusCompensationTask {

    private static final String SHOPPING_CART_KEY = "shopping_cart_order_number:";
    private final PlatformTransactionManager transactionManager;

    private final RedisCache redisCache;
    private final ISlkjOrderStatusCompensationService iSlkjOrderStatusCompensationService;
    private final LakalaMicroPayService lakalaMicroPayService;
    private final ISlkjOrderService iSlkjOrderService;
    private final SlkjOrderStatusLogMapper slkjOrderStatusLogMapper;
    private final SlkjShoppingCartMapper slkjShoppingCartMapper;



    @Scheduled(fixedDelay = 50000) // 每5秒执行一次
    public void compensateOrderStatus() {
        log.info("订单状态补偿任务执行开始");

        try {
            List<SlkjOrderStatusCompensation> statusCompensations = iSlkjOrderStatusCompensationService.queryListByStatus();
            if (CollectionUtils.isNotEmpty(statusCompensations)) {
                log.info("获取到符合条件数据，共：" + statusCompensations.size() + "条数据，开始执行！！！");

                for (SlkjOrderStatusCompensation statusCompensation : statusCompensations) {
                    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
                    try {
                        String preStatus = statusCompensation.getStatus();
                        TradeQueryResponse tradedQuery = lakalaMicroPayService.tradeQuery(statusCompensation.getPaymentRequestId(), statusCompensation.getShopId());
                        log.info("订单 [{}] 查询拉卡拉支付结果：{}", statusCompensation.getOrderId(), JSON.toJSONString(tradedQuery));

                        if (Objects.isNull(tradedQuery) || Objects.isNull(tradedQuery.getRespData())) {
                            continue; // 跳过没有响应的数据
                        }
                        TradeQueryResponse.RespData respData = tradedQuery.getRespData();
                        if (StringUtils.isEmpty(respData.getTradeState())) {
                            continue; // 跳过没有交易状态的数据
                        }

                        SlkjOrder order = iSlkjOrderService.selectSlkjOrderByOrderId(statusCompensation.getOrderId());
                        order.setPaymentStatus(respData.getTradeState());
                        order.setUpdateTime(DateUtils.getNowDate());

                        if (LakalaTradeStateEnum.SUCCESS.name().equals(respData.getTradeState())) {
                            if (StringUtils.isEmpty(respData.getAccSettleAmount())) {
                                continue; // 跳过没有结算金额的数据
                            }
                            order.setPaymentTime(DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, tradedQuery.getRespData().getTradeTime()));

                            // 处理小程序购物车逻辑
                            Object value = redisCache.getCacheObject(SHOPPING_CART_KEY + order.getOrderNumber());
                            if (Objects.nonNull(value)) {
                                log.info("用户支付成功，删除购物车对应数据：{}", value);
                                long[] shoppingCartIds = Splitter.on(",")
                                        .trimResults()
                                        .omitEmptyStrings()
                                        .splitToList(String.valueOf(value)).stream()
                                        .mapToLong(Long::parseLong)
                                        .toArray();
                                slkjShoppingCartMapper.deleteCart(shoppingCartIds);
                            }
                        }

                        // 更新订单状态
                        if (LakalaTradeStateEnum.SUCCESS.name().equals(order.getPaymentStatus())) {
                            updateOrderBusinessStatus(order);
                        }

                        // 更新实际金额
                        if (StringUtils.isNotEmpty(respData.getAccSettleAmount())) {
                            order.setActualAmount(Integer.parseInt(respData.getAccSettleAmount().replaceAll("^\"|\"$", "")));
                        }

                        if(StringUtils.isBlank(order.getThirdOrderNumber())){
                            order.setThirdOrderNumber(respData.getLogNo());
                        }

                        // 第三方交易单号
                        order.setAccTradeNo(respData.getAccTradeNo());

                        log.info("更新订单状态：{}", JSON.toJSONString(order));
                        iSlkjOrderService.updateSlkjOrder(order);

                        String paymentStatus = order.getPaymentStatus();
                        statusCompensation.setAttempts(statusCompensation.getAttempts() + 1);
                        statusCompensation.setStatus(paymentStatus);
                        statusCompensation.setUpdateTime(DateUtils.getNowDate());
                        log.info("更新订单状态补偿记录：{}", JSON.toJSONString(statusCompensation));
                        iSlkjOrderStatusCompensationService.update(statusCompensation);

                        if (!preStatus.equals(paymentStatus)) {
                            insertOrderStatusLog(order, paymentStatus);
                        }

                        // 提交事务
                        transactionManager.commit(status);
                    } catch (Exception e) {
                        // 出现异常时，回滚当前事务
                        transactionManager.rollback(status);
                        log.error("处理订单 [{}] 时出现异常，已回滚：{}", statusCompensation.getOrderId(), e.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            log.error("订单状态补偿任务执行异常：{}", e.getMessage());
        }
        log.info("订单状态补偿任务执行结束。");
    }

    private void updateOrderBusinessStatus(SlkjOrder order) {
        switch (OrderType.fromCode(order.getOrderType())) {
            case OT_101:
                order.setBusinessStatus(order.getSource() == OrderSource.SHOP.getCode() ? OrderBusinessStatus.REDEEMED.getCode() : OrderBusinessStatus.UNREDEEMED.getCode());
                break;
            case OT_102:
                order.setGoodsStatus(order.getSource() == OrderSource.SHOP.getCode() ? GoodsStatusEnum.COMPLETED.name() :
                        StringUtils.isNotBlank(order.getAddressSnapshot()) ? GoodsStatusEnum.WAITING_FOR_SHIPPING.name() : GoodsStatusEnum.WAITING_FOR_PICKUP.name());
                break;
            case OT_103:
                order.setBusinessStatus(OrderBusinessStatus.REDEEMED.getCode());
                order.setGoodsStatus(GoodsStatusEnum.COMPLETED.name());
                break;
        }
        // 删除旧的状态日志
        slkjOrderStatusLogMapper.deleteByOrderId(order.getOrderId());
    }

    private void insertOrderStatusLog(SlkjOrder order, String paymentStatus) {
        SlkjOrderStatusLog statusLog = new SlkjOrderStatusLog();
        statusLog.setOrderId(order.getOrderId());
        switch (LakalaTradeStateEnum.fromState(paymentStatus)) {
            case SUCCESS:
                statusLog.setStatus(order.getSource() == OrderSource.SHOP.getCode() ? OrderBusinessStatus.REDEEMED.getCode() : OrderBusinessStatus.UNREDEEMED.getCode());
                break;
            case CLOSE:
            case FAIL:
                statusLog.setStatus(OrderBusinessStatus.ORDER_CANCELLED.getCode());
                break;
            case REFUND:
                statusLog.setStatus(OrderBusinessStatus.REFUNDED.getCode());
                break;
            default:
                break;
        }
        if (StringUtils.isBlank(statusLog.getStatus())) {
            throw new RuntimeException("订单 [" + order.getOrderNumber() + "] 状态拉取异常，数据回滚！");
        }
        statusLog.setChangeTime(DateUtils.getNowDate());
        log.info("插入订单业务状态变更记录！:{}", JSON.toJSONString(statusLog));
        slkjOrderStatusLogMapper.insert(statusLog);
    }

}
